/*--------------------------------------
文件名称：log.c
文件功能：日志系统实现文件
说明：实现日志系统的具体功能
--------------------------------------*/
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* 即使在LOG_ENABLE为0的情况下也提供这些全局变量 */
#if LOG_ENABLE
const char *level_names[] = {
    "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};

const char *level_colors[] = {
    "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"
};
#else
const char *level_names[] = { "", "", "", "", "", "" };
const char *level_colors[] = { "", "", "", "", "", "" };
#endif

log_level_t g_log_level = LOG_INFO;
FILE *g_log_file = NULL;

#if LOG_ENABLE

/*--------------------------------------
函数名称：log_set_level
函数功能：设置日志级别
输入参数：log_level_t level - 要设置的日志级别
输出参数：None
说明：设置全局日志级别，低于此级别的日志将被忽略
--------------------------------------*/
void log_set_level(log_level_t level) {
    g_log_level = level;
}

/*--------------------------------------
函数名称：log_set_file
函数功能：设置日志输出文件
输入参数：const char *filename - 日志文件路径
输出参数：int - 成功返回1，失败返回0
说明：设置日志输出到指定文件，如果文件已存在则追加
--------------------------------------*/
int log_set_file(const char *filename) {
    if (g_log_file) {
        fclose(g_log_file);
    }
    g_log_file = fopen(filename, "a");
    return g_log_file != NULL;
}

/*--------------------------------------
函数名称：log_close_file
函数功能：关闭日志文件
输入参数：None
输出参数：None
说明：关闭当前打开的日志文件
--------------------------------------*/
void log_close_file(void) {
    if (g_log_file) {
        fclose(g_log_file);
        g_log_file = NULL;
    }
}

/*--------------------------------------
函数名称：log_log
函数功能：记录日志
输入参数：
    log_level_t level - 日志级别
    const char *file - 源文件名
    int line - 源文件行号
    const char *fmt - 格式化字符串
    ... - 可变参数
输出参数：None
说明：内部日志记录函数，被其他日志函数调用
--------------------------------------*/
void log_log(log_level_t level, const char *file, int line, const char *fmt, ...) {
    if (level < g_log_level) {
        return;
    }

    // 获取时间
    time_t t = time(NULL);
    struct tm *lt = localtime(&t);
    char time_str[20];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", lt);

    // 从文件路径中提取文件名
    const char *filename = strrchr(file, '/');
    if (filename) {
        filename++;
    } else {
        filename = strrchr(file, '\\');
        if (filename) {
            filename++;
        } else {
            filename = file;
        }
    }

    // 格式化日志消息
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);

    // 输出到控制台
    fprintf(stdout, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m %s\n",
            time_str, level_colors[level], level_names[level], 
            filename, line, buf);

    // 输出到文件
    if (g_log_file) {
        fprintf(g_log_file, "%s %-5s %s:%d: %s\n",
                time_str, level_names[level], filename, line, buf);
        fflush(g_log_file);
    }
}

/*--------------------------------------
函数名称：log_trace
函数功能：记录TRACE级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录调试跟踪信息
--------------------------------------*/
void log_trace(const char *fmt, ...) {
    if (LOG_TRACE < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_TRACE, __FILE__, __LINE__, "%s", buf);
}

/*--------------------------------------
函数名称：log_debug
函数功能：记录DEBUG级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录调试信息
--------------------------------------*/
void log_debug(const char *fmt, ...) {
    if (LOG_DEBUG < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_DEBUG, __FILE__, __LINE__, "%s", buf);
}

/*--------------------------------------
函数名称：log_info
函数功能：记录INFO级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录一般信息
--------------------------------------*/
void log_info(const char *fmt, ...) {
    if (LOG_INFO < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_INFO, __FILE__, __LINE__, "%s", buf);
}

/*--------------------------------------
函数名称：log_warn
函数功能：记录WARN级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录警告信息
--------------------------------------*/
void log_warn(const char *fmt, ...) {
    if (LOG_WARN < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_WARN, __FILE__, __LINE__, "%s", buf);
}

/*--------------------------------------
函数名称：log_error
函数功能：记录ERROR级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录错误信息
--------------------------------------*/
void log_error(const char *fmt, ...) {
    if (LOG_ERROR < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_ERROR, __FILE__, __LINE__, "%s", buf);
}

/*--------------------------------------
函数名称：log_fatal
函数功能：记录FATAL级别日志
输入参数：const char *fmt - 格式化字符串，... - 可变参数
输出参数：None
说明：记录致命错误信息
--------------------------------------*/
void log_fatal(const char *fmt, ...) {
    if (LOG_FATAL < g_log_level) {
        return;
    }
    
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    
    log_log(LOG_FATAL, __FILE__, __LINE__, "%s", buf);
}

#else /* LOG_ENABLE is 0 */

/* 即使LOG_ENABLE为0，也提供空函数实现，避免链接错误 */
void log_set_level(log_level_t level) { (void)level; }
int log_set_file(const char *filename) { (void)filename; return 0; }
void log_close_file(void) { }

void log_log(log_level_t level, const char *file, int line, const char *fmt, ...) { 
    (void)level; (void)file; (void)line; (void)fmt; 
    /* 确保不执行任何输出操作 */
}

void log_trace(const char *fmt, ...) { 
    (void)fmt;
    /* 确保不调用log_log */
}

void log_debug(const char *fmt, ...) { 
    (void)fmt; 
    /* 确保不调用log_log */
}

void log_info(const char *fmt, ...) { 
    (void)fmt; 
    /* 确保不调用log_log */
}

void log_warn(const char *fmt, ...) { 
    (void)fmt; 
    /* 确保不调用log_log */
}

void log_error(const char *fmt, ...) { 
    (void)fmt; 
    /* 确保不调用log_log */
}

void log_fatal(const char *fmt, ...) { 
    (void)fmt; 
    /* 确保不调用log_log */
}

#endif /* if LOG_ENABLE */